package com.ds.app.proxy;

import com.ds.app.*;
import com.ds.app.inner.EIModule;
import com.ds.common.cache.CacheSizes;
import com.ds.common.cache.Cacheable;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.org.*;
import com.ds.org.conf.OrgConfig;
import com.ds.org.conf.OrgConstants;
import com.ds.server.OrgManagerFactory;
import com.ds.server.eumus.ConfigCode;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class ModuleProxy implements Module, Cacheable, Serializable, Comparable<Module> {

    protected static Log log = LogFactory.getLog(OrgConstants.CONFIG_KEY.getType(), ModuleProxy.class);
    private ConfigCode configCode;

    private List<String> personIdList;
    boolean personIdList_is_initialized;

    private List<String> orgIdList;
    boolean orgIdList_is_initialized;

    private List<String> disablePersonIdList;
    boolean disablePersonIdList_is_initialized;

    private List<String> roleIdList;
    boolean roleIdList_is_initialized;

    private List<String> appIdList;
    boolean appIdList_is_initialized;
    private String ID;
    private EIModule module;
    private ModuleProxyManager manager;

    private OrgConfig getConfig() {
	OrgConfig config = OrgConfig.getInstance(this.configCode);
	return config;
    }

    public ModuleProxy(EIModule module, ConfigCode configCode) throws ModuleNotFoundException {
	if (configCode == null) {
		configCode = OrgConstants.CONFIG_KEY;
	}
	manager = ModuleProxyManager.getInstance(configCode);
	this.configCode = configCode;
	this.ID = module.getID();
	this.module = module;

    }

    public List<String> getOrgIdList() {
	prepareOrgs();
	if (orgIdList == null) {
	    return new ArrayList<String>();
	}
	return orgIdList;
    }

    public List<String> getRoleIdList() {
	prepareRoles();
	if (roleIdList == null) {
	    return new ArrayList();
	}
	return roleIdList;
    }

    public List<Role> getRoleList() {
	prepareRoles();
	if (roleIdList == null) {
	    return new ArrayList();
	}
	List personRoleList = new ArrayList();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = roleIdList.size(); i < n; i++) {
	    try {
		personRoleList.add(cacheManager.getRoleByID((String) roleIdList.get(i)));
	    } catch (RoleNotFoundException ex) {
	    }
	}
	return personRoleList;
    }

    /**
     * 取得人员所在所有组织机构
     * 
     * @return
     */
    public List<App> getAppList() {
	prepareApps();
	if (appIdList == null) {
	    return new ArrayList<App>();
	}
	List appList = new ArrayList();
	AppCacheManager cacheManager = AppCacheManager.getInstance(configCode);
	for (int i = 0, n = appIdList.size(); i < n; i++) {
	    try {
		appList.add(cacheManager.getAppByID((String) appIdList.get(i)));
	    } catch (AppNotFoundException ex) {
	    }
	}
	return appList;
    }

    public List<String> getAppIdList() {
	prepareApps();
	if (appIdList == null) {
	    return new ArrayList<String>();
	}
	return appIdList;
    }

    // 增加角色
    public void addRole(String roleId) {
	if (roleIdList == null) {
	    roleIdList = new ArrayList();
	}
	this.roleIdList.add(roleId);
    }

    // 增加具有权限使用人员
    public void addPerson(String personId) {
	if (personIdList == null) {
	    personIdList = new ArrayList();
	}
	this.personIdList.add(personId);
    }

    // 增加具有权限使用人员
    public void addOrg(String personId) {
	if (orgIdList == null) {
	    orgIdList = new ArrayList();
	}
	this.orgIdList.add(personId);
    }

    // 禁用人员
    public void addDisablePerson(String personId) {
	if (disablePersonIdList == null) {
	    disablePersonIdList = new ArrayList();
	}
	this.disablePersonIdList.add(personId);
    }


    // 5.增加组织
    public void addApp(String appId) {
	if (appIdList == null) {
	    appIdList = new ArrayList();
	}
	this.appIdList.add(appId);
    }

    /**
     * 判断人员是否已载入，如果未载入则载入
     */
    private void preparePersons() {
	if (!personIdList_is_initialized) {
	    manager.loadDisablePersons(this);
	}
    }

    /**
     * 判断人员是否已载入，如果未载入则载入
     */
    private void prepareOrgs() {
	if (!orgIdList_is_initialized) {
	    manager.loadOrgs(this);
	}
    }

    /**
     * 判断禁用人员是否已载入，如果未载入则载入
     */
    private void prepareDisablePersons() {
	if (!disablePersonIdList_is_initialized && getConfig().isSupportPersonDuty()) {
	    manager.loadDisablePersons(this);
	}
    }

    /**
     * 判断应用是否已载入，如果未载入则载入
     */
    private void prepareApps() {
	if (!appIdList_is_initialized) {
	    manager.loadApps(this);
	}
    }

 

    /**
     * 判断角色是否已载入，如果未载入则载入
     */
    private void prepareRoles() {
	if (!appIdList_is_initialized && getConfig().isSupportPersonRole()) {
	    manager.loadRoles(this);
	}
    }

    public List<Person> getDisablePersonList() {

	prepareDisablePersons();
	if (disablePersonIdList == null) {
	    return new ArrayList<Person>();
	}
	List<Person> personList = new ArrayList<Person>();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = disablePersonIdList.size(); i < n; i++) {
	    try {
		personList.add(cacheManager.getPersonByID((String) disablePersonIdList.get(i)));
	    } catch (PersonNotFoundException ex) {
	    }
	}
	return personList;
    }

    public List<Person> getPersonList() {
	preparePersons();
	if (personIdList == null) {
	    return new ArrayList<Person>();
	}
	List<Person> personList = new ArrayList<Person>();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = personIdList.size(); i < n; i++) {
	    try {
		personList.add(cacheManager.getPersonByID((String) personIdList.get(i)));
	    } catch (PersonNotFoundException ex) {
	    }
	}
	return personList;
    }

    public List<Org> getOrgList() {
	prepareOrgs();
	if (orgIdList == null) {
	    return new ArrayList<Org>();
	}
	List<Org> orgList = new ArrayList<Org>();
	OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = orgIdList.size(); i < n; i++) {
	    try {
		orgList.add(cacheManager.getOrgByID((String) orgIdList.get(i)));
	    } catch (OrgNotFoundException ex) {
	    }
	}
	return orgList;
    }

    public List<Person> getRightPersonList() {
	List<Person> personList = new ArrayList<Person>();
	
	List<Role> roleList = this.getRoleList();
	for (int k = 0; k < roleList.size(); k++) {
	    Role role = roleList.get(k);
	    List<Person> dpersonList = role.getPersonList();
	    for (int i = 0; i < dpersonList.size(); i++) {
		Person person = dpersonList.get(i);
		if (!personList.contains(person)) {
		    personList.add(person);
		}
		;
	    }
	}
	
	List<Org> orgList = this.getOrgList();
	for (int k = 0; k < orgList.size(); k++) {
	    Org org = orgList.get(k);
	    List<Person> dpersonList = org.getPersonListRecursively();
	    for (int i = 0; i < dpersonList.size(); i++) {
		Person person = dpersonList.get(i);
		if (!personList.contains(person)) {
		    personList.add(person);
		}
		;
	    }
	}
	return personList;
    }

    public List<Person> getAllRightPerson() {
	List<Person> personList = new ArrayList<Person>();

	List<Person> rightPersonList = this.getRightPersonList();
	List<Person> addPersonList = this.getPersonList();
	List<Person> disablePerson = this.getDisablePersonList();
	for (int k = 0; k < rightPersonList.size(); k++) {
	    Person person = rightPersonList.get(k);
	    if (!personList.contains(person)) {
		personList.add(person);
	    }
	    ;
	}
	for (int k = 0; k < addPersonList.size(); k++) {
	    Person person = addPersonList.get(k);
	    if (!personList.contains(person)) {
		personList.add(person);
	    }
	    ;
	}
	for (int k = 0; k < disablePerson.size(); k++) {
	    Person person = disablePerson.get(k);
	    if (personList.contains(person)) {
		personList.remove(person);
	    }
	    ;
	}
	return personList;
    }

    public int getCachedSize() {
	int size = 0;
	size += CacheSizes.sizeOfString(configCode.getType());
	size += CacheSizes.sizeOfList(personIdList);
	size += CacheSizes.sizeOfList(orgIdList);
	size += CacheSizes.sizeOfList(disablePersonIdList);
	
	size += CacheSizes.sizeOfList(roleIdList);

	return size;
    }

    @Override
    public int hashCode() {
	final int PRIME = 31;
	int result = 1;
	result = PRIME * result + ((ID == null) ? 0 : ID.hashCode());
	return result;
    }

    @Override
    public boolean equals(Object obj) {
	return this.module.equals(obj);

    }

    public EIModule getModule() {
	return module;
    }

    public void setModule(EIModule module) {
	this.module = module;
    }

    public int compareTo(Module o) {
	if (o.getIndex() > this.getIndex()) {
	    return 1;
	}
	return 0;
    }

    public String getEnName() {

	return module.getEnName();
    }

    public Integer getEnabled() {

	return module.getEnabled();
    }

    public String getID() {
	return module.getID();
    }

    public String getIcon() {

	return module.getIcon();
    }

    public Integer getIndex() {
	return module.getIndex();
    }

    public String getName() {
	return module.getName();
    }

    public Integer getNeedRight() {
	return module.getNeedRight();
    }

    public String getUrl() {
	return module.getUrl();
    }

    public boolean isAppIdList_is_initialized() {
	return appIdList_is_initialized;
    }

    public void setAppIdList_is_initialized(boolean appIdList_is_initialized) {
	this.appIdList_is_initialized = appIdList_is_initialized;
    }

    public List<String> getDisablePersonIdList() {
	return disablePersonIdList;
    }

    public void setDisablePersonIdList(List<String> disablePersonIdList) {
	this.disablePersonIdList = disablePersonIdList;
    }

    public boolean isDisablePersonIdList_is_initialized() {
	return disablePersonIdList_is_initialized;
    }

    public void setDisablePersonIdList_is_initialized(boolean disablePersonIdList_is_initialized) {
	this.disablePersonIdList_is_initialized = disablePersonIdList_is_initialized;
    }

    public boolean isOrgIdList_is_initialized() {
	return orgIdList_is_initialized;
    }

    public void setOrgIdList_is_initialized(boolean orgIdList_is_initialized) {
	this.orgIdList_is_initialized = orgIdList_is_initialized;
    }

    public List<String> getPersonIdList() {
	return personIdList;
    }

    public void setPersonIdList(List<String> personIdList) {
	this.personIdList = personIdList;
    }

    public boolean isPersonIdList_is_initialized() {
	return personIdList_is_initialized;
    }

    public void setPersonIdList_is_initialized(boolean personIdList_is_initialized) {
	this.personIdList_is_initialized = personIdList_is_initialized;
    }

    public boolean isRoleIdList_is_initialized() {
	return roleIdList_is_initialized;
    }

    public void setRoleIdList_is_initialized(boolean roleIdList_is_initialized) {
	this.roleIdList_is_initialized = roleIdList_is_initialized;
    }

    public void setAppIdList(List<String> appIdList) {
	this.appIdList = appIdList;
    }

    public void setOrgIdList(List<String> orgIdList) {
	this.orgIdList = orgIdList;
    }

    public void setRoleIdList(List<String> roleIdList) {
	this.roleIdList = roleIdList;
    }

}
